package com.thd.framework.db.utils;

import com.thd.framework.basic.exceptions.BasicException;
import com.thd.framework.basic.utils.ListUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Transactional(rollbackFor={Exception.class})
public class JdbcTemplateUtils {
    public static JdbcTemplate jdbcTemplate;

    public static Logger logger = LoggerFactory.getLogger(JdbcTemplateUtils.class);

    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        JdbcTemplateUtils.jdbcTemplate = jdbcTemplate;
    }

    public JdbcTemplateUtils(){}

    public static List<Map<String,Object>> queryForList(String sql, Object ...objs)  {
        logger.info("SQL:{}",sql);
        logger.info("PARAMS:{}",JdbcTemplateUtils.formatParam(objs));
        return JdbcTemplateUtils.jdbcTemplate.queryForList(sql,objs);
    };


    public static int update(String sql, Object ...objs)  {
        logger.info("SQL:{}",sql);
        logger.info("PARAMS:{}",JdbcTemplateUtils.formatParam(objs));
        return JdbcTemplateUtils.jdbcTemplate.update(sql,objs);
    };

    public static BigDecimal querySum(String sql, Object ...objs) {
        logger.info("SQL:{}",sql);
        logger.info("PARAMS:{}",JdbcTemplateUtils.formatParam(objs));

        List l = JdbcTemplateUtils.jdbcTemplate.queryForList(sql,objs);
        if(ListUtils.isEmpty(l)){
            return new BigDecimal(0);
        }
        if(l.size() != 1){
            BasicException.throwBasicException("More than one results return");
        }
        Object obj = l.get(0);
        if(null == obj){
            return new BigDecimal(0);
        }
        try{
            BigDecimal result = new BigDecimal(String.valueOf(obj));
            return result;
        }catch (Exception e){
            BasicException.throwBasicException("Result of query can not be transfer BigDecimal");
            return null;
        }

    };

    public static Map queryOne(String sql, Object ...objs) {
        logger.info("SQL:{}",sql);
        logger.info("PARAMS:{}",JdbcTemplateUtils.formatParam(objs));
        List<Map<String,Object>> l = JdbcTemplateUtils.jdbcTemplate.queryForList(sql,objs);
        if(ListUtils.isEmpty(l)){
            return null;
        }
        if(l.size() != 1){
            BasicException.throwBasicException("More than one results return");
        }
        return l.get(0);
    };


    public static String formatParam(Object ...objs){
        if(null == objs ){
            return "";
        }
        if(objs.length<=0){
            return "";
        }
        return Arrays.asList(objs).stream().map(item -> {
            String r = "";
            try{
                r = item.toString();
            }catch (Exception e){
                r = "[error]";
            }
            return r;
        }).collect(Collectors.joining(" , "));

    }
}
